package cc.wanforme.fsync.server.service.impl;

import cc.wanforme.fsync.entity.ClientNodeInfo;
import cc.wanforme.fsync.entity.GroupMapVo;
import cc.wanforme.fsync.entity.po.GroupMap;
import cc.wanforme.fsync.entity.po.TickTaskGroup;
import cc.wanforme.fsync.server.ServerCenter;
import cc.wanforme.fsync.server.mapper.GroupMapMapper;
import cc.wanforme.fsync.server.mapper.TickTaskGroupMapper;
import cc.wanforme.fsync.server.service.ITickTaskGroupService;
import cc.wanforme.st.server.exception.MunkRuntimeException;
import cc.wanforme.st.server.util.AssertCheck;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class TickTaskGroupServiceImpl extends ServiceImpl<TickTaskGroupMapper, TickTaskGroup>
        implements ITickTaskGroupService {

    private GroupMapMapper groupMapMapper;
    private ServerCenter serverCenter;

    @Override
    public TickTaskGroup saveVo(TickTaskGroup vo) {
        AssertCheck.nonNull(vo.getTaskId(), "task is empty");
        AssertCheck.nonNull(vo.getGroupMapId(), "group is empty");

        if (existed(vo.getTaskId(), vo.getGroupMapId(), null)) {
            throw new MunkRuntimeException("This is existed!");
        }

        this.save(vo);
        return vo;
    }

    @Override
    public TickTaskGroup updateVo(TickTaskGroup vo) {
        AssertCheck.nonNull(vo.getTaskId(), "task is empty");
        AssertCheck.nonNull(vo.getGroupMapId(), "group is empty");

        if (existed(vo.getTaskId(), vo.getGroupMapId(), vo.getId())) {
            throw new MunkRuntimeException("This is existed!");
        }

        this.updateById(vo);
        return vo;
    }

    @Override
    public void deleteByVo(TickTaskGroup vo) {
        Long id = vo.getId();
        if(id != null) {
            removeById(id);
            return;
        }

        TickTaskGroup ttg = baseMapper.getByTaskAndGroup(vo.getTaskId(), vo.getGroupMapId());
        if(ttg != null) {
            removeById(ttg);
        }
    }

    /**
     * 判断是否存在。
     *
     * @return
     */
    private boolean existed(Long taskId, Long groupMapId, Long ignoreId) {
        TickTaskGroup group = this.baseMapper.getByTaskAndGroup(taskId, groupMapId);
        if (group == null) {
            return false;
        }

        if (ignoreId != null && ignoreId.longValue() == group.getId().longValue()) {
            return false;
        }
        return true;
    }

    @Override
    public List<GroupMap> listGroupMapByTask(Long taskId) {
        List<TickTaskGroup> groups = this.baseMapper.listByTask(taskId);
        List<GroupMap> realGMs = new ArrayList<>();
        for (TickTaskGroup tg : groups) {
            GroupMap groupMap = groupMapMapper.selectById(tg.getGroupMapId());
            if (groupMap != null) {
                realGMs.add(groupMap);
            }
        }

        return realGMs;
    }
    public List<GroupMapVo> listInfoByTask(Long taskId) {
        List<GroupMap> list = listGroupMapByTask(taskId);
        List<GroupMapVo> voList = list.stream().map(e -> {
            GroupMapVo vo = new GroupMapVo(e);
            ClientNodeInfo tartget = serverCenter.getInfoById(e.getTargetClient());
            vo.setTargetClientNode(tartget);

            if (e.getSourceClient() != null) {
                ClientNodeInfo source = serverCenter.getInfoById(e.getSourceClient());
                vo.setSourceClientNode(source);
            }

            // todo 路径所在分区的空间大小
            return vo;
        }).collect(Collectors.toList());
        return voList;
    }

    @Override
    public void deleteByGroupMap(Long id) {
        this.baseMapper.deleteByGroupMap(id);
    }

    @Autowired
    public void setGroupMapMapper(GroupMapMapper groupMapMapper) {
        this.groupMapMapper = groupMapMapper;
    }
    @Autowired
    @Lazy
    public void setServerCenter(ServerCenter serverCenter) {
        this.serverCenter = serverCenter;
    }
}
